package com.ruyiadmin.springboot.common.listeners.system;

import cn.hutool.core.io.FileUtil;
import com.ruyiadmin.springboot.common.beans.system.DirectoryConfig;
import com.ruyiadmin.springboot.common.beans.system.LogConfig;
import com.ruyiadmin.springboot.common.events.system.SysLogEvent;
import com.ruyiadmin.springboot.common.exceptions.RuYiAdminCustomException;
import com.ruyiadmin.springboot.domain.entity.system.SysEsLog;
import com.ruyiadmin.springboot.domain.entity.system.SysLog;
import com.ruyiadmin.springboot.repository.system.ISysEsLogRepository;
import com.ruyiadmin.springboot.service.iservices.system.ISysLogService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.modelmapper.ModelMapper;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.Charset;

/**
 * <p>
 * 系统日志监听事件
 * </p>
 *
 * @author RuYiAdmin
 * @since 2022-07-20
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class SysLogListener {

    //region 监听私有属性

    private final ISysLogService logService;
    private final MongoTemplate mongoTemplate;
    private final LogConfig logConfig;
    private final DirectoryConfig directoryConfig;
    private final ISysEsLogRepository esLogRepository;
    private final ModelMapper modelMapper;

    //endregion

    //region 日志监控日志

    @Async
    @Order
    @EventListener(SysLogEvent.class)
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveSysLog(SysLogEvent event) throws Exception {
        SysLog sysLog = (SysLog) event.getSource();

        //处理返回结果
        if (!StringUtils.isEmpty(sysLog.getResult()) && sysLog.getResult().length() > 2000) {

            String monitoringLogsPath = String.join("", this.directoryConfig.getMonitoringLogsPath(),
                    "/", sysLog.getId(), ".txt");
            FileUtil.newFile(monitoringLogsPath);
            FileUtil.appendString(sysLog.getResult(), monitoringLogsPath, Charset.defaultCharset());

            sysLog.setResult(sysLog.getResult().substring(0, 2000) + "...");
        }

        if (this.logConfig.isSupportMongoDB()) {
            //日志存入MongoDB
            this.mongoTemplate.save(sysLog);
        } else if (this.logConfig.isSupportElasticsearch()) {
            //日志存入Elasticsearch
            SysEsLog esLog = this.modelMapper.map(sysLog, SysEsLog.class);
            try {
                esLog.setCreateTime(DateTime.now().toDate());
                esLog.setModifyTime(DateTime.now().toDate());
                esLogRepository.save(esLog);
            } catch (Exception exception) {
                if (!(exception.getMessage()).contains("Created")) {
                    throw new RuYiAdminCustomException(exception.getMessage());
                }
            }
        } else if (this.logConfig.isSupportMeilisearch()) {
            //日志存入Meilisearch

        } else {
            //日志存入关系库
            this.logService.save(sysLog);
        }
    }

    //endregion

}
